// 静态分配写法
#include <iostream>
#include <pthread.h>
#include <vector>
#include <string>
#include <unistd.h>

using namespace std;

int tickets = 1000;  // 1000张票
#define THREAD_NUM 4 // 4个售票窗口

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

class threadData
{
public:
    threadData(int number /*, pthread_mutex_t *mutex*/)
    {
        threadname = "thread-" + to_string(number);
        // lock = mutex;
    }

public:
    string threadname;
    // pthread_mutex_t *lock;
};

void *getTicket(void *args)
{
    threadData *td = static_cast<threadData *>(args);
    const char *name = td->threadname.c_str();
    while (true)
    {
        // 加锁
        // pthread_mutex_lock(td->lock); // 线程申请锁资源，申请成功执行，失败则阻塞
        pthread_mutex_lock(&lock);

        // ==================== 临界区 =====================
        if (tickets > 0) // 有票就抢
        {
            usleep(1000); // 抢票花的时间
            printf("who = %s, get a ticket: %d\n", name, tickets);
            --tickets;
            // 解锁
            // pthread_mutex_unlock(td->lock);
            pthread_mutex_unlock(&lock);
        }
        else
        {
            // 解锁
            // pthread_mutex_unlock(td->lock);
            pthread_mutex_unlock(&lock);
            break;
        }
        // ==================== 临界区 =====================
        usleep(13); // 让其他线程有机会申请到锁资源
    }
    printf("%s ... quit\n", name);
    return nullptr;
}

int main()
{

    // ======== 初始化互斥锁 ======
    // pthread_mutex_init(&lock, nullptr);

    vector<pthread_t> tids;
    vector<threadData *> thread_datas;

    for (int i = 1; i <= THREAD_NUM; i++)
    {
        pthread_t tid;
        threadData *td = new threadData(i /*, &lock*/);
        thread_datas.push_back(td);
        pthread_create(&tid, nullptr, getTicket, thread_datas[i - 1]);
        tids.push_back(tid);
    }
    for (auto thread : tids)
    {
        pthread_join(thread, nullptr);
    }
    for (auto td : thread_datas)
    {
        delete td;
    }

    // ===== 销毁互斥锁 =====
    // pthread_mutex_destroy(&lock);
    return 0;
}

// 动态分配写法
// #include <iostream>
// #include <pthread.h>
// #include <vector>
// #include <string>
// #include <unistd.h>

// using namespace std;

// int tickets = 1000;  // 1000张票
// #define THREAD_NUM 4 // 4个售票窗口

// class threadData
// {
// public:
//     threadData(int number, pthread_mutex_t *mutex)
//     {
//         threadname = "thread-" + to_string(number);
//         lock = mutex;
//     }

// public:
//     string threadname;
//     pthread_mutex_t *lock;
// };

// void *getTicket(void *args)
// {
//     threadData *td = static_cast<threadData *>(args);
//     const char *name = td->threadname.c_str();
//     while (true)
//     {
//         // 加锁
//         pthread_mutex_lock(td->lock); // 线程申请锁资源，申请成功执行，失败则阻塞
//         // ==================== 临界区 =====================
//         if (tickets > 0) // 有票就抢
//         {
//             usleep(1000); // 抢票花的时间
//             printf("who = %s, get a ticket: %d\n", name, tickets);
//             --tickets;
//             // 解锁
//             pthread_mutex_unlock(td->lock);
//         }
//         else
//         {
//             // 解锁
//             pthread_mutex_unlock(td->lock);
//             break;
//         }
//         // ==================== 临界区 =====================
//         usleep(13); // 让其他线程有机会申请到锁资源
//     }
//     printf("%s ... quit\n", name);
//     return nullptr;
// }

// int main()
// {
//     // ======== 定义互斥锁  ======
//     pthread_mutex_t lock;
//     // ======== 初始化互斥锁 ======
//     pthread_mutex_init(&lock, nullptr);

//     vector<pthread_t> tids;
//     vector<threadData *> thread_datas;

//     for (int i = 1; i <= THREAD_NUM; i++)
//     {
//         pthread_t tid;
//         threadData *td = new threadData(i, &lock);
//         thread_datas.push_back(td);
//         pthread_create(&tid, nullptr, getTicket, thread_datas[i - 1]);
//         tids.push_back(tid);
//     }
//     for (auto thread : tids)
//     {
//         pthread_join(thread, nullptr);
//     }
//     for (auto td : thread_datas)
//     {
//         delete td;
//     }

//     // ===== 销毁互斥锁 =====
//     pthread_mutex_destroy(&lock);
//     return 0;
// }